package cn.com.hhrcw.enterprise.web;

import cn.com.hhrcw.conferenceRoom.entity.ConferenceRoom;
import cn.com.hhrcw.conferenceRoom.mapstruct.ConferenceRoomConvert;
import cn.com.hhrcw.conferenceRoom.service.IConferenceRoomService;
import cn.com.hhrcw.conferenceRoomBatch.entity.ConferenceRoomBatch;
import cn.com.hhrcw.conferenceRoomBatch.mapstruct.ConferenceRoomBatchConvert;
import cn.com.hhrcw.conferenceRoomBatch.service.IConferenceRoomBatchService;
import cn.com.hhrcw.enterprise.params.OpInterviewHistoryParams;
import cn.com.hhrcw.enterprise.service.EnterpriseService;
import cn.com.hhrcw.enterprise.vo.*;
import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.mapstruct.*;
import cn.com.hhrcw.service.*;
import cn.com.hhrcw.sms.service.ISysSmsTemplateService;
import cn.com.hhrcw.statistics.IStatisticsService;
import cn.com.hhrcw.statistics.entity.Statistics;
import cn.com.hhrcw.utils.AgeUtil;
import cn.com.hhrcw.utils.DateUtil;
import cn.com.hhrcw.utils.EmailUtil;
import cn.com.hhrcw.utils.NewsUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 首页相关信息
 *
 * @program: recruit-boot-parent
 * @description: 首页相关信息
 * @author: JD
 * @create: 2020-10-31 09:56
 **/
@RestController
@RequestMapping("/en/index")
@Slf4j
public class IndexMessageController {

    @Autowired
    private IOpDeliveryHistoryService deliveryHistoryService;

    @Autowired
    private IOpJobService jobService;

    @Autowired
    private IOpInterviewHistoryService interviewHistoryService;

    @Autowired
    private IOpEntryHistoryService entryHistoryService;

    @Autowired
    private IEnInfoService enInfoService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    EnterpriseService enterpriseService;

    @Autowired
    private IOpInterviewHistoryService opnterviewHistoryService;

    @Autowired
    private EnOpInterviewHistoryConvert enOpInterviewHistoryConvert;

    @Autowired
    private IPiInfoService infoService;

    @Autowired
    private EnPiInfoConvert enPiInfoConvert;

    @Autowired
    private EnOpJobConvert jobConvert;

    @Autowired
    private EnCvResumeConvert resumeConvert;

    @Autowired
    private IEnContactsService contactService;

    @Autowired
    private EnEnContactsConvert enEnContactsConvert;

    @Autowired
    ISysUserDepartService userDepartService;

    @Autowired
    private EnEnInfoConvert enInfoConvert;

    @Autowired
    ICvResumeService resumeService;

    @Autowired
    IFileService fileService;

    @Autowired
    IOpInterviewContactService interviewContactService;

    @Autowired
    private IStatisticsService statisticsService;

    @Autowired
    private EmailUtil emailUtil;

    @Autowired
    private NewsUtil newsUtil;

    @Autowired
    private ISysSmsTemplateService templateService;

    /**
     * 结束面试
     *
     * @return
     */
    @AutoLog(logType = 0, ty = "visit", value = "结束面试")
    @GetMapping("/viewEnd")
    public Result<?> viewEnd(String id) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        OpInterviewHistory opInterviewHistory = opnterviewHistoryService.getById(id);
        Assert.notNull(opInterviewHistory, "数据不存在！");
        opInterviewHistory.setOnLineState(1);
        opInterviewHistory.setUpdateBy(sysUser.getUsername());
        opInterviewHistory.setUpdateTime(new Date());
        opnterviewHistoryService.updateById(opInterviewHistory);
        return Result.ok();
    }

    /**
     * 开始面试
     *
     * @return
     */
    @AutoLog(logType = 0, ty = "visit", value = "开始面试")
    @GetMapping("/viewStart")
    public Result<?> viewStart(String id) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        OpInterviewHistory opInterviewHistory = opnterviewHistoryService.getById(id);
        Assert.notNull(opInterviewHistory, "数据不存在！");
        //发送站内信
        newsUtil.creatNews(opInterviewHistory.getUserId(), sysUser.getId(), 0, 1, opInterviewHistory.getId(), "14");
        //发送微信
        Map<String, String> emailMap = emailUtil.creatEmail(opInterviewHistory.getUserId(), sysUser.getId(),
            0, 1, opInterviewHistory.getId(), "14");
        String title = emailMap.get("tittle");
        String content = emailMap.get("content");
        //发送短信
        PiInfo piInfo = infoService.lambdaQuery().eq(PiInfo::getUserId, opInterviewHistory.getUserId()).one();
        templateService.sendSms(new String[]{piInfo.getPhone()}, "【" + title + "】" + content);
        opInterviewHistory.setOnLineState(2);
        opInterviewHistory.setUpdateBy(sysUser.getUsername());
        opInterviewHistory.setUpdateTime(new Date());
        opnterviewHistoryService.updateById(opInterviewHistory);
        return Result.ok();
    }

    /**
     * 在线预览简历，二进制流形式
     *
     * @param userId   用户id
     * @param langType 语言类型0中文1英文
     * @param type     0在线简历1附件简历
     */
    @GetMapping("/getResumeBriny")
    @AutoLog(logType = 2, ty = "visit", value = "在线预览简历")
    public ResponseEntity getResumeBriny(String userId, Integer langType, Integer type, String jobId, HttpServletResponse response) {
        String url = "";
        if (type != null && type == 1) {
            CvResume cvResume = resumeService.lambdaQuery().eq(CvResume::getDelFlag, false).eq(CvResume::getUserId, userId)
                .eq(CvResume::getType, 1).one();
            if (cvResume != null) {
                File file = fileService.getById(cvResume.getFileId());
                url = file.getFilePath();
            }
            java.io.File file = new java.io.File(url);
            byte[] bytes = new byte[0];
            if (file.exists()) {
                bytes = FileUtil.readBytes(file);
            }
            return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_PDF)
                .contentLength(bytes.length)
                .body(new ByteArrayResource(bytes));
        } else {
            CvResume cvResume = resumeService.lambdaQuery().eq(CvResume::getDelFlag, false).eq(CvResume::getUserId, userId)
                .eq(CvResume::getType, 0).eq(CvResume::getLanType, langType).one();
            if (cvResume != null) {
                if (langType == 0) {
                    url = org.apache.commons.lang.StringUtils.isNotBlank(cvResume.getPdfPath()) ? cvResume.getPdfPath() : resumeService.getResumeInfoPDF(cvResume.getUserId(), 0, jobId);
                } else {
                    url = org.apache.commons.lang3.StringUtils.isNotBlank(cvResume.getPdfPathEn()) ? cvResume.getPdfPathEn() : resumeService.getResumeInfoPDF(cvResume.getUserId(), 1, jobId);
                }
            }
            java.io.File file = new java.io.File(url);
            String html = "";
            if (file.exists()) {
                html = FileUtil.readString(file, StandardCharsets.UTF_8);
            }
            return ResponseEntity.ok()
                .contentType(MediaType.TEXT_HTML)
                .contentLength(file.length())
                .body(html);
        }
    }

    /**
     * 根据userId获取在线简历信息
     *
     * @param userId  用户id,必传
     * @param lanType 简历语言:0中文1英文,必传
     * @return
     */
    @Deprecated
    @GetMapping("/getResumeInfoByUserId")
    public Result<ResumeInfoVO> getResumeInfo(String userId, Integer lanType) {
        ResumeInfoVO vo = enterpriseService.getResumeInfo(userId, lanType);
        return Result.ok(vo);
    }

    /**
     * 首页-数字统计
     *
     * @return
     */
    @GetMapping("/message")
    @AutoLog(logType = 2, ty = "visit", value = "首页数字统计")
    public Result<IndexMessageVO> indexMessage() {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        //招聘中的职位
        List<OpJob> jobs = this.jobService.lambdaQuery()
            .eq(OpJob::getDelFlag, false)
            .eq(OpJob::getCompanyId, sysUser.getCompanyId())
            .eq(OpJob::getRecruitmentState, 0)
            .select(OpJob::getId)
            .list();
        if (CollUtil.isEmpty(jobs)) {
            return Result.ok(new IndexMessageVO());
        }
        IndexMessageVO vo = new IndexMessageVO();
        //职位
        vo.setOnLineJobCount(jobs.size());
        Integer newCount = deliveryHistoryService.lambdaQuery()
            .in(OpDeliveryHistory::getState, 0, 1)
            .in(OpDeliveryHistory::getJobId, jobs.stream().map(OpJob::getId).toArray())
            .count();
        vo.setNewResumeCount(newCount);

        LambdaQueryChainWrapper<OpInterviewHistory> wrapper = this.interviewHistoryService.lambdaQuery()
            .eq(OpInterviewHistory::getDelFlag, false)
            .eq(OpInterviewHistory::getCompanyId, sysUser.getCompanyId());
        //自己是面试官
        List<OpInterviewContact> contacts = interviewContactService.lambdaQuery()
            .eq(OpInterviewContact::getDelFlag, false)
            .eq(OpInterviewContact::getContactId, sysUser.getId())
            .select(OpInterviewContact::getViewId)
            .list();
        List<String> viewHistoryList = new ArrayList<>();
        if (CollUtil.isNotEmpty(contacts)) {
            viewHistoryList.addAll(contacts.stream().map(OpInterviewContact::getViewId).collect(Collectors.toList()));
        }
        //自己是联系人
        List<EnContacts> enContactsList = contactService.lambdaQuery()
            .eq(EnContacts::getDelFlag, false)
            .eq(EnContacts::getCompanyId, sysUser.getCompanyId())
            .eq(EnContacts::getPhone, sysUser.getPhone())
            .select(EnContacts::getId)
            .list();
        if (CollUtil.isEmpty(contacts) && CollUtil.isEmpty(enContactsList)) {
            return Result.ok(vo);
        }

        if (CollUtil.isNotEmpty(viewHistoryList)) {
            wrapper.and(ew -> {
                ew.in(OpInterviewHistory::getId, viewHistoryList);
                if (CollUtil.isNotEmpty(enContactsList)) {
                    ew.or().in(OpInterviewHistory::getContactId, enContactsList.stream().map(EnContacts::getId).toArray());
                }
                return ew;
            });
        }
        List<OpInterviewHistory> histories = wrapper.list();
        if (CollUtil.isEmpty(histories)) {
            return Result.ok(vo);
        }
        //待面试
        long noInterviewCount = histories.stream().filter(e -> {
            if (e.getOutLineState() == null || e.getOnLineState() == null) {
                return false;
            }
            return e.getOutLineState() == 1 && e.getOnLineState() == 0 && e.getViewResult() == null;
        }).count();
        //已面试待处理
        long processedInterviewCount = histories.stream().filter(e -> {
            if (e.getOutLineState() == null || e.getOnLineState() == null) {
                return false;
            }
            return e.getOutLineState() == 1 && e.getOnLineState() == 2 && e.getViewResult() == null;
        }).count();
        //待录用
        long noEmployedCount = histories.stream().filter(e -> {
            if (e.getOutLineState() == null || e.getOnLineState() == null || e.getViewResult() == null) {
                return false;
            }
            long count = entryHistoryService.lambdaQuery()
                .eq(OpEntryHistory::getDelFlag, false)
                .eq(OpEntryHistory::getUserId, e.getUserId())
                .eq(OpEntryHistory::getJobId, e.getJobId())
                .count();
            return e.getOutLineState() == 1 && e.getOnLineState() == 1 && e.getViewResult() == 0 && count == 0;
        }).count();
        //待入职
        long noEntryCount = histories.stream().filter(e -> {
            OpEntryHistory one = entryHistoryService.lambdaQuery()
                .eq(OpEntryHistory::getDelFlag, false)
                .eq(OpEntryHistory::getUserId, e.getUserId())
                .eq(OpEntryHistory::getJobId, e.getJobId())
                .eq(OpEntryHistory::getAcceptFlag, 1)
                .one();
            return e.getViewResult() != null && e.getViewResult() == 0 && one != null && one.getEntryFlag() == null;
        }).count();
        vo.setProcessedInterviewCount((int) processedInterviewCount);
        vo.setNoInterviewCount((int) noInterviewCount);
        vo.setNoEmployedCount((int) noEmployedCount);
        vo.setNoEntryCount((int) noEntryCount);

        return Result.ok(vo);
    }

    private List<OpInterviewHistory> getHistories(List<String> viewIds, List<String> conIds) {
        List<OpInterviewHistory> histories;
        if (CollectionUtils.isEmpty(viewIds) && !CollectionUtils.isEmpty(conIds)) {
            histories = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getDelFlag, false).
                and(query -> query.in(OpInterviewHistory::getContactId, conIds)).orderByDesc(OpInterviewHistory::getCreateTime).list();
        } else if (!CollectionUtils.isEmpty(viewIds) && CollectionUtils.isEmpty(conIds)) {
            histories = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getDelFlag, false).
                and(query -> query.in(OpInterviewHistory::getId, viewIds)).orderByDesc(OpInterviewHistory::getCreateTime).list();
        } else {
            histories = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getDelFlag, false).
                and(query -> query.in(OpInterviewHistory::getId, viewIds).or().in(OpInterviewHistory::getContactId, conIds)).orderByDesc(OpInterviewHistory::getCreateTime).list();
        }
        return histories;
    }

    /**
     * 首页-招聘进展 (招聘报表-招聘进展)
     *
     * @return
     */
    @GetMapping("/progressToal")
    @AutoLog(logType = 2, ty = "visit", value = "招聘进展")
    public Result<IndexProgressVO> progressTotal() {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        IndexProgressVO vo = new IndexProgressVO();
        Statistics statistics = statisticsService.queryByCompany(loginUser.getCompanyId());
        List<OpJob> jobs = this.jobService.lambdaQuery().eq(OpJob::getDelFlag, false).eq(OpJob::getCompanyId, loginUser.getCompanyId()).eq(OpJob::getRecruitmentState, 0).list();
        vo.setOnLineJobCount(jobs.size());
        vo.setPlanCount(statistics.getRecruitment());
        vo.setSurplusCount(statistics.getRemaining());
        vo.setScreenCount(statistics.getTotal() - statistics.getFilterBySystem());
        vo.setFirstStepScreenCount(statistics.getFilterFirst());
        vo.setInterviewCount(statistics.getInterview());
        vo.setAlreadyInterviewCount(statistics.getAlreadyInterview());
        vo.setAlreadyNoticeCount(statistics.getOffer());
        vo.setAlreadyEntryCount(statistics.getAccession());
        return Result.ok(vo);
    }

    /**
     * 首页-招聘进展,本年度 (招聘报表-招聘进展)
     *
     * @return
     */
    @GetMapping("/progress")
    @AutoLog(logType = 2, ty = "visit", value = "本年度招聘进展")
    public Result<IndexProgressVO> progress() {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        SysUserDepart userDepart = userDepartService.lambdaQuery().eq(SysUserDepart::getUserId, sysUser.getId()).one();
        String companyId = userDepart.getDepId();
        IndexProgressVO result = new IndexProgressVO();
        LambdaQueryWrapper<OpDeliveryHistory> hisQuery = new LambdaQueryWrapper<>();
        Date thisYear = DateUtil.getCurrYearFirstTime();

        LambdaQueryWrapper<OpJob> jobLambdaQueryWrapper = new LambdaQueryWrapper<>();
        jobLambdaQueryWrapper.eq(OpJob::getCompanyId, companyId).eq(OpJob::getDelFlag, false).eq(OpJob::getRecruitmentState, 0);
        List<OpJob> jobs = jobService.list(jobLambdaQueryWrapper);

        if (CollectionUtils.isEmpty(jobs)) {
            return Result.ok(new IndexProgressVO());
        }

        List<String> jobIds = new ArrayList<>();
        jobs.forEach(e -> {
            jobIds.add(e.getId());
            result.setPlanCount(result.getPlanCount() + e.getNeedCount());
        });
        result.setOnLineJobCount(jobs.size());

        hisQuery.eq(OpDeliveryHistory::getDelFlag, false).eq(OpDeliveryHistory::getCompanyId, companyId).ge(OpDeliveryHistory::getCreateTime, thisYear).in(OpDeliveryHistory::getJobId, jobIds);
        List<OpDeliveryHistory> histories = deliveryHistoryService.list(hisQuery);
        if (!CollectionUtils.isEmpty(histories)) {
            histories.forEach(e -> {
                //0 未阅读 1 已阅读  2 不合适 3 通过筛选 4  面试 5已发offer(已录用)6 已入职 7 被过滤
                boolean flag = e.getState() == 2 || e.getState() == 3;
                if (flag) {
                    result.setScreenCount(result.getScreenCount() + 1);//初筛和不合适
                }
                boolean flagTwo = e.getState() != 3;
                if (flagTwo) {
                    result.setFirstStepScreenCount(result.getFirstStepScreenCount() + 1);
                }
                switch (e.getState()) {
                    case 4:
                        result.setInterviewCount(result.getInterviewCount() + 1);
                        break;
                    case 5:
                        result.setAlreadyNoticeCount(result.getAlreadyNoticeCount() + 1);
                        break;
                    case 6:
                        result.setAlreadyEntryCount(result.getAlreadyEntryCount() + 1);
                        break;
                    default:
                        break;
                }
            });
        }
        LambdaQueryWrapper<OpInterviewHistory> viewQuery = new LambdaQueryWrapper<>();
        viewQuery.eq(OpInterviewHistory::getDelFlag, false).le(OpInterviewHistory::getTime, new Date()).ge(OpInterviewHistory::getCreateTime, thisYear);
        int viewCount = interviewHistoryService.count(viewQuery);
        result.setAlreadyInterviewCount(viewCount);
        result.setAlreadyEntryCount(result.getPlanCount() - result.getAlreadyEntryCount());
        return Result.ok(result);
    }

    /**
     * 获取近七天简历投递量
     *
     * @return
     */
    @GetMapping("/sevenInfo")
    @AutoLog(logType = 2, ty = "visit", value = "近七天简历投递量")
    public Result<SevenDaysInfoVO> doSevenDays() {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        SysUserDepart userDepart = userDepartService.lambdaQuery().eq(SysUserDepart::getUserId, sysUser.getId()).one();
        String companyId = userDepart.getDepId();
        SevenDaysInfoVO result = new SevenDaysInfoVO();
        List<OpDeliveryHistory> list = jdbcTemplate.query("select * from `op_delivery_history`  where DATE_SUB(CURDATE(), INTERVAL 6 DAY) <= date(create_time) and company_id= ? ORDER BY create_time", new Object[]{companyId}, new BeanPropertyRowMapper<>(OpDeliveryHistory.class));
        result.doSevenDays(list);
        return Result.ok(result);
    }

    /**
     * 首页-面试日程
     * 面试日程是未面试或者面试了但没通过的
     *
     * @param params 请求参数
     * @return
     */
    @GetMapping(value = "/list")
    @AutoLog(logType = 2, ty = "visit", value = "面试日程")
    public Result<Page<OpInterviewHistoryVO>> list(OpInterviewHistoryParams params, HttpServletRequest request) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        LambdaQueryWrapper<OpInterviewHistory> queryWrapper = getPageResult(params, sysUser);
        if (queryWrapper == null) {
            return Result.ok(new Page<>());
        }
        queryWrapper.eq(OpInterviewHistory::getOutLineState, 1);
        queryWrapper.isNull(OpInterviewHistory::getViewResult);
        //时间段
        if (params.getDayFlag() != null) {
            Date start = new Date();
            long zero = DateUtil.getTodayZero();
            start.setTime(zero);
            Date end = new Date();
            end.setTime(zero + 86400000);
            switch (params.getDayFlag()) {
                case 1:
                    queryWrapper.lt(OpInterviewHistory::getTime, start);
                    break;
                case 2:
                    queryWrapper.ge(OpInterviewHistory::getTime, start).lt(OpInterviewHistory::getTime, end);
                    break;
                case 3:
                    queryWrapper.ge(OpInterviewHistory::getTime, end);
                    break;
                default:
                    break;
            }
        }
        //自己是面试官
        List<OpInterviewContact> contacts = interviewContactService.lambdaQuery().eq(OpInterviewContact::getDelFlag, false).eq(OpInterviewContact::getContactId, sysUser.getId()).select(OpInterviewContact::getViewId).list();
        List<String> viewIds = new ArrayList<>();
        contacts.forEach(e -> {
            viewIds.add(e.getViewId());
        });
        //自己是联系人
        List<EnContacts> enContactsList = contactService.lambdaQuery().eq(EnContacts::getDelFlag, false).eq(EnContacts::getPhone, sysUser.getPhone()).list();
        List<String> conIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(enContactsList)) {
            enContactsList.forEach(e -> {
                conIds.add(e.getId());
            });
        }
        IPage<OpInterviewHistory> page = null;
        if (CollectionUtils.isEmpty(viewIds) && CollectionUtils.isEmpty(conIds)) {
            return Result.ok(new Page<>());
        }
        if (CollectionUtils.isEmpty(viewIds) && !CollectionUtils.isEmpty(conIds)) {
            queryWrapper.eq(OpInterviewHistory::getDelFlag, false).
                and(query -> query.in(OpInterviewHistory::getContactId, conIds)).eq(OpInterviewHistory::getOutLineState, 1).eq(OpInterviewHistory::getOutLineState, 1).orderByDesc(OpInterviewHistory::getCreateTime);
            page = opnterviewHistoryService.page(params.page(), queryWrapper);
        } else if (!CollectionUtils.isEmpty(viewIds) && CollectionUtils.isEmpty(conIds)) {
            queryWrapper.eq(OpInterviewHistory::getDelFlag, false).
                and(query -> query.in(OpInterviewHistory::getId, viewIds)).eq(OpInterviewHistory::getOutLineState, 1).eq(OpInterviewHistory::getOutLineState, 1).orderByDesc(OpInterviewHistory::getCreateTime);
            page = opnterviewHistoryService.page(params.page(), queryWrapper);
        } else {
            queryWrapper.eq(OpInterviewHistory::getDelFlag, false).
                and(query -> query.in(OpInterviewHistory::getId, viewIds).or().in(OpInterviewHistory::getContactId, conIds)).eq(OpInterviewHistory::getOutLineState, 1).eq(OpInterviewHistory::getOutLineState, 1).orderByDesc(OpInterviewHistory::getCreateTime);
            page = opnterviewHistoryService.page(params.page(), queryWrapper);
        }
        //分页结果转换器
        Function<OpInterviewHistory, OpInterviewHistoryVO> fun = getOpInterviewHistoryOpInterviewHistoryVoFunction();
        return Result.ok((Page) page.convert(fun));
    }

    private Function<OpInterviewHistory, OpInterviewHistoryVO> getOpInterviewHistoryOpInterviewHistoryVoFunction() {
        return opInterviewHistory -> {
            OpInterviewHistoryVO vo = enOpInterviewHistoryConvert.toVO(opInterviewHistory);
            LambdaQueryWrapper<PiInfo> infoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            infoLambdaQueryWrapper.eq(PiInfo::getDelFlag, false).eq(PiInfo::getUserId, vo.getUserId());
            PiInfo user = infoService.getOne(infoLambdaQueryWrapper);
            vo.setUserInfo(enPiInfoConvert.toVO(user));
            if (vo.getUserInfo().getJobTime() != null) {
                int workYears = AgeUtil.getAge(vo.getUserInfo().getJobTime());
                vo.getUserInfo().setWorkYears(workYears);
            }
            OpJob job = jobService.getById(vo.getJobId());
            vo.setJob(jobConvert.toVO(job));
            OpDeliveryHistory deliveryHistory = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getUserId, opInterviewHistory.getUserId()).eq(OpDeliveryHistory::getJobId, opInterviewHistory.getJobId()).eq(OpDeliveryHistory::getDelFlag, false).one();
            if (deliveryHistory != null) {
                vo.setDelId(deliveryHistory.getId());
                vo.setReState(deliveryHistory.getState());
                CvResume cvResume = resumeService.getById(deliveryHistory.getResumeId());
                vo.setResumeVO(resumeConvert.toVO(cvResume));
            }
            EnInfo enInfo = enInfoService.getById(job.getCompanyId());
            vo.setEnInfo(enInfoConvert.toVO(enInfo));
            EnContacts enContacts = contactService.getById(vo.getContactId());
            vo.setContact(enEnContactsConvert.toVO(enContacts));
            if (opInterviewHistory.getTime().getTime() < System.currentTimeMillis()) {
                if (opInterviewHistory.getViewResult() == null) {
                    vo.setState(1);
                } else {
                    if (opInterviewHistory.getViewResult() == 1) {
                        vo.setState(3);
                    } else if (opInterviewHistory.getViewResult() == 0) {
                        vo.setState(2);
                    }
                }
            } else {
                vo.setState(0);
            }
            Integer type = opInterviewHistory.getType();
            if (type == 0) {
                vo.setTimeFlag(System.currentTimeMillis() > opInterviewHistory.getTime().getTime());
            } else {
                vo.setTimeFlag(System.currentTimeMillis() > opInterviewHistory.getInterviewEndTime().getTime());
                if (StrUtil.isNotBlank(vo.getRoomId())) {
                    ConferenceRoom conferenceRoom = conferenceRoomService.getById(vo.getRoomId());
                    vo.setConferenceRoomVO(conferenceRoomConvert.toVO(conferenceRoom));
                    ConferenceRoomBatch conferenceRoomBatch = conferenceRoomBatchService.getById(vo.getBatchId());
                    vo.setConferenceRoomBatchVO(conferenceRoomBatchConvert.toVO(conferenceRoomBatch));
                }
            }
            return vo;
        };
    }

    private LambdaQueryWrapper<OpInterviewHistory> getPageResult(OpInterviewHistoryParams params, LoginUser sysUser) {
        LambdaQueryWrapper<OpInterviewHistory> queryWrapper = new LambdaQueryWrapper<>();
        //筛选职位名称
        if (StringUtils.isNotBlank(params.getJobName())) {
            LambdaQueryWrapper<OpJob> jobQuery = new LambdaQueryWrapper<>();
            jobQuery.eq(OpJob::getDelFlag, false).eq(OpJob::getCreateBy, sysUser.getId()).like(OpJob::getJobName, params.getJobName());
            List<OpJob> jobs = jobService.list(jobQuery);
            if (CollectionUtils.isEmpty(jobs)) {
                return null;
            } else {
                List<String> jobIds = new ArrayList<>();
                jobs.forEach(e -> {
                    jobIds.add(e.getId());
                });
                queryWrapper.in(OpInterviewHistory::getJobId, jobIds);
            }
        }
        if (StrUtil.isNotBlank(params.getRoomId())) {
            queryWrapper.eq(OpInterviewHistory::getRoomId, params.getRoomId());
        } else if (params.getType() == 1) {
            List<ConferenceRoom> rooms = conferenceRoomService.lambdaQuery().eq(ConferenceRoom::getCompanyId, sysUser.getCompanyId()).list();
            if (CollectionUtils.isEmpty(rooms)) {
                return null;
            } else {
                queryWrapper.in(OpInterviewHistory::getRoomId, rooms.stream().map(ConferenceRoom::getId).collect(Collectors.toList()));
            }
        }
        queryWrapper.eq(OpInterviewHistory::getType, params.getType());
        if (StringUtils.isNotBlank(params.getEnName())) {
            List<EnInfo> enInfos = enInfoService.lambdaQuery().like(EnInfo::getEnName, params.getEnName()).list();
            if (CollectionUtils.isEmpty(enInfos)) {
                return null;
            } else {
                List<String> enIds = new ArrayList<>();
                enInfos.forEach(e -> {
                    enIds.add(e.getId());
                });
                LambdaQueryWrapper<OpJob> jobQuery = new LambdaQueryWrapper<>();
                jobQuery.eq(OpJob::getDelFlag, false).in(OpJob::getCompanyId, enIds);
                List<OpJob> jobs = jobService.list(jobQuery);
                if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(jobs)) {
                    return null;
                } else {
                    List<String> jobIds = new ArrayList<>();
                    jobs.forEach(e -> {
                        jobIds.add(e.getId());
                    });
                    queryWrapper.in(OpInterviewHistory::getJobId, jobIds);
                }
            }
        }
        //应聘者手机号或姓名
        if (StringUtils.isNotBlank(params.getNameOrPhone())) {
            LambdaQueryWrapper<PiInfo> piQuery = new LambdaQueryWrapper<>();
            piQuery.eq(PiInfo::getDelFlag, false).and(wrapper -> wrapper.like(PiInfo::getPhone, params.getNameOrPhone()).or().like(PiInfo::getName, params.getNameOrPhone()));
            List<PiInfo> infos = infoService.list(piQuery);
            if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(infos)) {
                List<String> userIds = new ArrayList<>();
                infos.forEach(e -> {
                    userIds.add(e.getUserId());
                });
                queryWrapper.in(OpInterviewHistory::getUserId, userIds);
            } else {
                return null;
            }
        }
        if (StringUtils.isNotBlank(params.getJobName())) {
            LambdaQueryWrapper<OpJob> jobQuery = new LambdaQueryWrapper<>();
            jobQuery.eq(OpJob::getDelFlag, false).like(OpJob::getJobName, params.getJobName());
            List<OpJob> jobs = jobService.list(jobQuery);
            if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(jobs)) {
                return null;
            } else {
                List<String> jobIds = new ArrayList<>();
                jobs.forEach(e -> {
                    jobIds.add(e.getId());
                });
                queryWrapper.in(OpInterviewHistory::getJobId, jobIds);
            }
        }
        return queryWrapper;
    }

    @Autowired
    private IConferenceRoomService conferenceRoomService;

    @Autowired
    private IConferenceRoomBatchService conferenceRoomBatchService;

    @Autowired
    private ConferenceRoomConvert conferenceRoomConvert;

    @Autowired
    private ConferenceRoomBatchConvert conferenceRoomBatchConvert;

    /**
     * 面试过了 还没发入职邀请的
     * 首页-录用日程-待录用
     *
     * @param params
     * @param request
     * @return
     */
    @GetMapping("/employmentList")
    @AutoLog(logType = 2, ty = "visit", value = "录用日程-待录用")
    public Result<Page<EmploymentListVO>> employmentList(OpInterviewHistoryParams params, HttpServletRequest request) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        LambdaQueryChainWrapper<OpInterviewHistory> wrapper = opnterviewHistoryService.lambdaQuery()
            .eq(OpInterviewHistory::getDelFlag, false)
            .eq(OpInterviewHistory::getOutLineState, 1)
            .eq(OpInterviewHistory::getOnLineState, 1)
            .eq(OpInterviewHistory::getViewResult, 0)
            .eq(OpInterviewHistory::getCompanyId, sysUser.getCompanyId())
            .orderByDesc(OpInterviewHistory::getCreateTime);
        //自己是面试官
        List<OpInterviewContact> contacts = interviewContactService.lambdaQuery()
            .eq(OpInterviewContact::getDelFlag, false)
            .eq(OpInterviewContact::getContactId, sysUser.getId())
            .select(OpInterviewContact::getViewId)
            .list();
        List<String> viewHistoryList = new ArrayList<>();
        if (CollUtil.isNotEmpty(contacts)) {
            viewHistoryList.addAll(contacts.stream().map(OpInterviewContact::getViewId).collect(Collectors.toList()));
        }
        //自己是联系人
        List<EnContacts> enContactsList = contactService.lambdaQuery()
            .eq(EnContacts::getDelFlag, false)
            .eq(EnContacts::getCompanyId, sysUser.getCompanyId())
            .eq(EnContacts::getPhone, sysUser.getPhone())
            .select(EnContacts::getId)
            .list();

        if (CollUtil.isEmpty(contacts) && CollUtil.isEmpty(enContactsList)) {
            return Result.ok(new Page<>());
        }
        //职位名称
        if (StrUtil.isNotBlank(params.getJobName())) {
            List<OpJob> jobs = this.jobService.lambdaQuery()
                .eq(OpJob::getDelFlag, false)
                .like(OpJob::getJobName, params.getJobName())
                .select(OpJob::getId)
                .list();
            if (CollUtil.isEmpty(jobs)) {
                return Result.ok(new Page<>());
            }
            wrapper.in(OpInterviewHistory::getJobId, jobs.stream().map(OpJob::getId).toArray());
        }
        //应聘者姓名/电话
        if (StrUtil.isNotBlank(params.getNameOrPhone())) {
            List<PiInfo> users = this.infoService.lambdaQuery()
                .eq(PiInfo::getDelFlag, false)
                .and(ew -> ew.like(PiInfo::getName, params.getNameOrPhone()).or().eq(PiInfo::getPhone, params.getNameOrPhone()))
                .select(PiInfo::getUserId)
                .list();
            if (CollUtil.isEmpty(users)) {
                return Result.ok(new Page<>());
            }
            wrapper.in(OpInterviewHistory::getJobId, users.stream().map(PiInfo::getUserId).toArray());
        }
        // 0不限制 1今天之前 2今天 3 今天后
        if (params.getDayFlag() != null) {
            DateTime date = cn.hutool.core.date.DateUtil.date();
            String format = date.toString(DatePattern.NORM_DATE_PATTERN);
            switch (params.getDayFlag()) {
                case 1:
                    wrapper.lt(OpInterviewHistory::getTime, format);
                    break;
                case 2:
                    wrapper.likeRight(OpInterviewHistory::getTime, format);
                    break;
                case 3:
                    wrapper.gt(OpInterviewHistory::getTime, format);
                    break;
                default:
                    break;
            }
        }

        List<OpEntryHistory> list = this.entryHistoryService.lambdaQuery()
            .eq(OpEntryHistory::getDelFlag, false)
            .eq(OpEntryHistory::getCompanyId, sysUser.getCompanyId())
            .list();

        //过滤已发入职邀请的记录
        if (CollUtil.isNotEmpty(list)) {
            LambdaQueryChainWrapper<OpInterviewHistory> entryWrapper = opnterviewHistoryService.lambdaQuery()
                .eq(OpInterviewHistory::getDelFlag, false)
                .eq(OpInterviewHistory::getCompanyId, sysUser.getCompanyId())
                .select(OpInterviewHistory::getId);
            entryWrapper.and(ew -> {
                for (OpEntryHistory opEntryHistory : list) {
                    ew.or(wra -> {
                        wra.eq(OpInterviewHistory::getUserId, opEntryHistory.getUserId())
                            .eq(OpInterviewHistory::getJobId, opEntryHistory.getJobId());
                        return wra;
                    });
                }
                return ew;
            });
            List<OpInterviewHistory> histories = entryWrapper.list();
            if (CollUtil.isNotEmpty(histories)) {
                wrapper.notIn(OpInterviewHistory::getId, histories.stream().map(OpInterviewHistory::getId).toArray());
            }
        }
        if (CollUtil.isNotEmpty(viewHistoryList)) {
            wrapper.and(ew -> {
                ew.in(OpInterviewHistory::getId, viewHistoryList);
                if (CollUtil.isNotEmpty(enContactsList)) {
                    ew.or().in(OpInterviewHistory::getContactId, enContactsList.stream().map(EnContacts::getId).toArray());
                }
                return ew;
            });
        }
        IPage<OpInterviewHistory> page = wrapper.page(params.page());
        //分页结果转换器
        Function<OpInterviewHistory, EmploymentListVO> fun = opInterviewHistory -> {
            EmploymentListVO vo = new EmploymentListVO();
            LambdaQueryWrapper<PiInfo> infoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            infoLambdaQueryWrapper.eq(PiInfo::getDelFlag, false).eq(PiInfo::getUserId, opInterviewHistory.getUserId());
            PiInfo user = infoService.getOne(infoLambdaQueryWrapper);
            vo.setUserInfo(enPiInfoConvert.toVO(user));
            OpJob job = jobService.getById(opInterviewHistory.getJobId());
            vo.setJobInfo(jobConvert.toVO(job));
            vo.setId(opInterviewHistory.getId());
            EnInfo enInfo = enInfoService.getById(job.getCompanyId());
            vo.setEnInfo(enInfoConvert.toVO(enInfo));
            vo.setResumeId(opInterviewHistory.getResumeId());
            OpDeliveryHistory deliveryHistory = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getUserId, opInterviewHistory.getUserId()).eq(OpDeliveryHistory::getJobId, opInterviewHistory.getJobId()).eq(OpDeliveryHistory::getDelFlag, false).one();
            if (deliveryHistory != null) {
                vo.setDelId(deliveryHistory.getId());
                vo.setReState(deliveryHistory.getState());
            }
            CvResume resume = resumeService.getById(opInterviewHistory.getResumeId());
            vo.setResumeVO(resumeConvert.toVO(resume));
            EnContacts enContacts = contactService.getById(opInterviewHistory.getContactId());
            vo.setContacts(enEnContactsConvert.toVO(enContacts));
            vo.setState(0);
            return vo;
        };

        return Result.ok((Page) page.convert(fun));
    }

    /**
     * 已发入职通知
     * 首页-录用日程-待入职
     *
     * @param params
     * @param request
     * @return
     */
    @GetMapping("/employmentList/v2")
    @AutoLog(logType = 2, ty = "visit", value = "录用日程-待入职")
    public Result<Page<EmploymentListVO>> employmentListV2(OpInterviewHistoryParams params, HttpServletRequest request) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        LambdaQueryChainWrapper<OpInterviewHistory> wrapper = this.interviewHistoryService.lambdaQuery()
            .eq(OpInterviewHistory::getDelFlag, false)
            .eq(OpInterviewHistory::getOutLineState, 1)
            .eq(OpInterviewHistory::getOnLineState, 1)
            .eq(OpInterviewHistory::getViewResult, 0)
            .eq(OpInterviewHistory::getCompanyId, sysUser.getCompanyId());
        //自己是面试官
        List<OpInterviewContact> contacts = interviewContactService.lambdaQuery()
            .eq(OpInterviewContact::getDelFlag, false)
            .eq(OpInterviewContact::getContactId, sysUser.getId())
            .select(OpInterviewContact::getViewId)
            .list();
        if (CollUtil.isNotEmpty(contacts)) {
            wrapper.in(OpInterviewHistory::getId, contacts.stream().map(OpInterviewContact::getViewId).toArray());
        }
        //自己是联系人
        List<EnContacts> enContactsList = contactService.lambdaQuery()
            .eq(EnContacts::getDelFlag, false)
            .eq(EnContacts::getCompanyId, sysUser.getCompanyId())
            .eq(EnContacts::getPhone, sysUser.getPhone())
            .select(EnContacts::getId)
            .list();
        if (CollUtil.isNotEmpty(enContactsList)) {
            wrapper.in(OpInterviewHistory::getContactId, enContactsList.stream().map(EnContacts::getId).toArray());
        }

        if (CollUtil.isEmpty(contacts) && CollUtil.isEmpty(enContactsList)) {
            return Result.ok(new Page<>());
        }
        //职位名称
        if (StrUtil.isNotBlank(params.getJobName())) {
            List<OpJob> jobs = this.jobService.lambdaQuery()
                .eq(OpJob::getDelFlag, false)
                .like(OpJob::getJobName, params.getJobName())
                .select(OpJob::getId)
                .list();
            if (CollUtil.isEmpty(jobs)) {
                return Result.ok(new Page<>());
            }
            wrapper.in(OpInterviewHistory::getJobId, jobs.stream().map(OpJob::getId).toArray());
        }
        //应聘者姓名/电话
        if (StrUtil.isNotBlank(params.getNameOrPhone())) {
            List<PiInfo> users = this.infoService.lambdaQuery()
                .eq(PiInfo::getDelFlag, false)
                .and(ew -> ew.like(PiInfo::getName, params.getNameOrPhone()).or().eq(PiInfo::getPhone, params.getNameOrPhone()))
                .select(PiInfo::getUserId)
                .list();
            if (CollUtil.isEmpty(users)) {
                return Result.ok(new Page<>());
            }
            wrapper.in(OpInterviewHistory::getJobId, users.stream().map(PiInfo::getUserId).toArray());
        }
        List<OpInterviewHistory> histories = wrapper.list();
        if (CollUtil.isEmpty(histories)) {
            return Result.ok(new Page<>());
        }

        LambdaQueryChainWrapper<OpEntryHistory> entryWrap = this.entryHistoryService.lambdaQuery()
            .eq(OpEntryHistory::getDelFlag, false)
            .orderByDesc(OpEntryHistory::getCreateTime);
        entryWrap.and(ew -> {
            for (OpInterviewHistory history : histories) {
                ew.or(ew1 -> {
                    ew1.eq(OpEntryHistory::getUserId, history.getUserId())
                        .eq(OpEntryHistory::getJobId, history.getJobId())
                        .isNull(OpEntryHistory::getEntryFlag)
                        .eq(OpEntryHistory::getAcceptFlag, 1);
                    return ew1;
                });
            }
            return ew;
        });
        IPage<OpEntryHistory> page = entryWrap.page(params.page());
        //分页结果转换器
        Function<OpEntryHistory, EmploymentListVO> fun = getOpEntryHistoryEmploymentListVoFunction();
        return Result.ok((Page) page.convert(fun));
    }

    private Boolean getPageResult(OpInterviewHistoryParams params, LambdaQueryWrapper<OpEntryHistory> queryWrapper) {
        //应聘者手机号或姓名
        if (StringUtils.isNotBlank(params.getNameOrPhone())) {
            LambdaQueryWrapper<PiInfo> piQuery = new LambdaQueryWrapper<>();
            piQuery.eq(PiInfo::getDelFlag, false).and(wrapper -> wrapper.like(PiInfo::getPhone, params.getNameOrPhone()).or().like(PiInfo::getName, params.getNameOrPhone()));
            List<PiInfo> infos = infoService.list(piQuery);
            if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(infos)) {
                List<String> userIds = new ArrayList<>();
                infos.forEach(e -> {
                    userIds.add(e.getUserId());
                });
                queryWrapper.in(OpEntryHistory::getUserId, userIds);
            } else {
                return false;
            }
        }
        //时间段
        if (params.getDayFlag() != null) {
            Date start = new Date();
            long zero = DateUtil.getTodayZero();
            start.setTime(zero);
            Date end = new Date();
            end.setTime(zero + 86400000);
            switch (params.getDayFlag()) {
                case 1:
                    queryWrapper.lt(OpEntryHistory::getTime, start);
                    break;
                case 2:
                    queryWrapper.ge(OpEntryHistory::getTime, start).lt(OpEntryHistory::getTime, end);
                    break;
                case 3:
                    queryWrapper.ge(OpEntryHistory::getTime, end);
                    break;
                default:
                    break;
            }
        }
        return true;
    }

    private Function<OpEntryHistory, EmploymentListVO> getOpEntryHistoryEmploymentListVoFunction() {
        return entryHistory -> {
            EmploymentListVO vo = new EmploymentListVO();
            LambdaQueryWrapper<PiInfo> infoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            infoLambdaQueryWrapper.eq(PiInfo::getDelFlag, false).eq(PiInfo::getUserId, entryHistory.getUserId());
            PiInfo user = infoService.getOne(infoLambdaQueryWrapper);
            vo.setUserInfo(enPiInfoConvert.toVO(user));
            OpJob job = jobService.getById(entryHistory.getJobId());
            vo.setJobInfo(jobConvert.toVO(job));
            vo.setId(entryHistory.getId());
            EnInfo enInfo = enInfoService.getById(job.getCompanyId());
            vo.setEnInfo(enInfoConvert.toVO(enInfo));

            OpDeliveryHistory deliveryHistory = deliveryHistoryService.lambdaQuery().eq(OpDeliveryHistory::getUserId, entryHistory.getUserId()).eq(OpDeliveryHistory::getJobId, entryHistory.getJobId()).eq(OpDeliveryHistory::getDelFlag, false).one();
            if (deliveryHistory != null) {
                vo.setDelId(deliveryHistory.getId());
                vo.setReState(deliveryHistory.getState());
                CvResume resume = resumeService.getById(deliveryHistory.getResumeId());
                vo.setResumeVO(resumeConvert.toVO(resume));
                vo.setResumeId(deliveryHistory.getResumeId());
            }
            EnContacts enContacts = contactService.getById(entryHistory.getContactId());
            vo.setContacts(enEnContactsConvert.toVO(enContacts));
            vo.setState(1);
            vo.setTime(entryHistory.getTime());
            return vo;
        };
    }

}
